package cc.momas.v1;

import java.io.CharArrayReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @author Sod-Momas
 * @since 2020/11/10
 */
public class LexerApplicationDemo2 {
    public static void main(String[] args) {
//        String script = "int age = 20 \"afefawefe\"";
        String script = "int3 age222222222222222222222222=\"2999999999990\" int\"afefawefe\"";
        List<Token> tokenList = tokenize(script);
        for (Token token : tokenList) {
            System.out.println(token);
        }
    }

    private static List<Token> tokenize(String script) {
        try (final CharArrayReader reader = new CharArrayReader(script.toCharArray())) {
            final List<Token> tokenList;
            tokenList = tokenize(reader);
            return tokenList;
        } catch (IOException e) {
            return Collections.emptyList();
        }
    }

    private static List<Token> tokenize(CharArrayReader reader) throws IOException {
        List<Token> tokenList = new ArrayList<>();
        char cur;
        int tmp;
        Token token = new Token();
        while ((tmp = reader.read()) != -1) {
            cur = (char) tmp;
            DfaStates state = token.getTokenState();
            // 新token
            if (null == state) {
                token = initToken(cur);
                continue;
            }

            switch (state) {
                case ID -> {
                    if (Character.isDigit(cur) || Character.isAlphabetic(cur)) {
                        // 还是id，继续拼接
                        token.tokenText.append(cur);
                    } else {
                        // 确定是个标识符
                        token.setTokenType(TokenType.IDENTIFIER);
                        tokenList.add(token);
                        // 新开token
                        token = initToken(cur);
                    }
                }
                case NUMBER_LITERAL -> {
                    if (Character.isDigit(cur)) {
                        token.tokenText.append(cur);
                    } else {
                        // 确定是个标识符
                        token.setTokenType(TokenType.NUMBER_LITERAL);
                        tokenList.add(token);
                        // 新开token
                        token = initToken(cur);

                    }
                }
                case STRING_LITERAL -> {
                    if (cur == '"') {
                        tokenList.add(token);
                        // 新开token
                        token = new Token();
                    } else {
                        token.tokenText.append(cur);
                    }
                }
                case INT1 -> {
                    if (cur == 'n') {
                        // 还是int
                        token.tokenText.append(cur);
                        token.tokenState = DfaStates.INT2;
                    } else if (Character.isDigit(cur) || Character.isAlphabetic(cur)) {
                        // 不是int了
                        token.tokenText.append(cur);
                        token.tokenState = DfaStates.ID;
                    } else {
                        // 确定是个标识符
                        token.setTokenType(TokenType.IDENTIFIER);
                        tokenList.add(token);
                        // 新开token
                        token = initToken(cur);
                    }
                }
                case INT2 -> {
                    if (cur == 't') {
                        // 还是int
                        token.tokenText.append(cur);
                        token.tokenState = DfaStates.INT3;
                    } else if (Character.isDigit(cur) || Character.isAlphabetic(cur)) {
                        // 不是int了
                        token.tokenText.append(cur);
                        token.tokenState = DfaStates.ID;
                    } else {
                        // 确定是个标识符
                        token.setTokenType(TokenType.IDENTIFIER);
                        tokenList.add(token);
                        // 新开token
                        token = initToken(cur);
                    }
                }
                case INT3 -> {
                    if (Character.isDigit(cur) || Character.isAlphabetic(cur)) {
                        token.tokenText.append(cur);
                        token.tokenType = TokenType.IDENTIFIER;
                        token.tokenState = DfaStates.ID;
                    } else {
                        // 确定是个标识符
                        token.setTokenType(TokenType.INT_KEYWORD);
                        tokenList.add(token);
                        // 新开token
                        token = initToken(cur);
                    }
                }
                case ASSIGNMENT -> {
                    // 确定是个标识符
                    token.setTokenType(TokenType.ASSIGNMENT);

                    tokenList.add(token);
                    // 新开token
                    token = initToken(cur);
                }
            }
        }
//        initToken(token, cur);
        return tokenList;
    }

    private static Token initToken(char cur) {
        // 新token
        Token token = new Token();
        if (cur == '"') {
            token.tokenType = TokenType.STRING_LITERAL;
            token.tokenState = DfaStates.STRING_LITERAL;
            return token;
        }
        token.tokenText.append(cur);
        if (Character.isDigit(cur)) {
            token.tokenType = TokenType.NUMBER_LITERAL;
            token.tokenState = DfaStates.NUMBER_LITERAL;
            return token;
        }
        if (cur == 'i') {
            token.tokenType = TokenType.INT_KEYWORD;
            token.tokenState = DfaStates.INT1;
            return token;
        }
        if (cur == '=') {
            token.tokenType = TokenType.ASSIGNMENT;
            token.tokenState = DfaStates.ASSIGNMENT;
            return token;
        }

        // 未知token
        token.tokenType = null;
        token.tokenState = null;
        return token;

    }
}
